package com.nbsaas.boot;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

import java.io.IOException;
import java.io.OutputStream;

public abstract class Controller<T, R> implements HttpHandler {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 处理请求，返回响应
    @Override
    public void handle(HttpExchange exchange) throws IOException {
        // 只接受 POST 请求
        if ("POST".equals(exchange.getRequestMethod())) {
            String requestBody = getRequestBody(exchange);
            T requestObject = deserializeJson(requestBody, getRequestClass());

            // 处理请求并返回响应
            R responseObject = handleRequest(requestObject);

            // 将响应对象序列化为 JSON
            String jsonResponse = serializeJson(responseObject);

            sendJsonResponse(exchange, jsonResponse);
        } else {
            String errorResponse = "{\"error\": \"Method Not Allowed\"}";
            sendJsonResponse(exchange, errorResponse);
        }
    }

    // 子类需要实现的请求处理逻辑
    protected abstract R handleRequest(T requestObject);

    // 获取请求体并转化为字符串
    private String getRequestBody(HttpExchange exchange) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        try (java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(exchange.getRequestBody()))) {
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
        }
        return stringBuilder.toString();
    }

    // 获取请求的类
    protected abstract Class<T> getRequestClass();

    // 将 JSON 字符串反序列化为对象
    private T deserializeJson(String json, Class<T> clazz) throws IOException {
        return objectMapper.readValue(json, clazz);
    }

    // 将对象序列化为 JSON 字符串
    private String serializeJson(R object) throws IOException {
        return objectMapper.writeValueAsString(object);
    }

    // 发送 JSON 响应
    private void sendJsonResponse(HttpExchange exchange, String jsonResponse) throws IOException {
        exchange.getResponseHeaders().set("Content-Type", "application/json");
        exchange.sendResponseHeaders(200, jsonResponse.getBytes().length);
        try (OutputStream os = exchange.getResponseBody()) {
            os.write(jsonResponse.getBytes());
        }
    }
}
